using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace Midgard
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Rectangle viewportrec;
        GameState gameState;
        Player player;
        List <Enemy> enemies;

        // Keyboard states used to determine key presses.
        KeyboardState currentKeyboardState;
        KeyboardState previousKeyBoardState;

        // Gamepad states used to determine button presses.
        GamePadState currentGamePadState;
        GamePadState previousGamePadState;


        /* All the images */
        Texture2D background;
        Texture2D playerSprite;
        Texture2D projectileTexture;

        TimeSpan fireTime;
        TimeSpan previousFireTime;

        int score;
        SpriteFont scoreFont;

        SoundsManager soundsObj;

        enum GameState
        {
            StartScreen, PlayingScreen, GameOverScreen
        };


        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            score = 0;


            soundsObj = new SoundsManager();
  
  

            graphics.PreferredBackBufferWidth = 700;
            graphics.PreferredBackBufferHeight = 800;
            graphics.ApplyChanges();

            gameState = GameState.StartScreen;

            base.Initialize();
        }


        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            background = Content.Load<Texture2D>("Mountainbackground");

            playerSprite = Content.Load<Texture2D>("serpent_spritesheet");
            projectileTexture = Content.Load<Texture2D>("shot");
            Projectile.texture = projectileTexture;

            /* This is a useful rectangle that tells you the size of your game */
            viewportrec = new Rectangle(0, 0, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height);

            player = new Player(new Vector2(0, viewportrec.Height - 87), playerSprite, viewportrec, projectileTexture);

            scoreFont = Content.Load<SpriteFont>("gameFont");


            soundsObj.loadSounds(Content.Load<Song>("sound/gameMusic"));
        }

        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit at any state
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed 
                || Keyboard.GetState().IsKeyDown(Keys.Escape) )
                this.Exit();

            if (gameState == GameState.StartScreen)
            {
                if (Keyboard.GetState().IsKeyDown(Keys.Space))
                    gameState = GameState.PlayingScreen;
            }
            else if (gameState == GameState.PlayingScreen)
            {
                player.update(gameTime);
            }
            else if (gameState == GameState.GameOverScreen)
            {
                if (Keyboard.GetState().IsKeyDown(Keys.Space))
                    gameState = GameState.StartScreen;
            }
            else
            {
                //ERROR
            }

            //keyState(); // Call to save previous state of keys.

            //controlPlayer(gameTime);

            //player.update(gameTime);

            /* If the Space bar key is pressed, the Serpent will fire 
            if (currentKeyboardState.IsKeyDown(Keys.Space) && gameTime.TotalGameTime - previousFireTime > fireTime)
            {
                // Reset our current time
                previousFireTime = gameTime.TotalGameTime;
            }
            */

            //updateProjectiles();


            base.Update(gameTime);
        }

        /**
         * Saves the previous state of the keyboard and gamepad. Also reads current state of the keyboard and gamepad and stores it.
         */
        /*
        private void keyState()
        {
            // Save the previous state.
            previousGamePadState = currentGamePadState;
            previousKeyBoardState = currentKeyboardState;

            // Read the current state.
            currentKeyboardState = Keyboard.GetState();
            currentGamePadState = GamePad.GetState(PlayerIndex.One);
        }
        */

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Azure);

            spriteBatch.Begin();
            if (gameState == GameState.StartScreen)
            {
            }
            else if (gameState == GameState.PlayingScreen)
            {
                spriteBatch.Draw(background, Vector2.Zero, Color.White);
                
       
                player.draw(spriteBatch);

                drawScore();
            }
            else if (gameState == GameState.GameOverScreen)
            {
            }
            else
            {
                //ERROR


            }




            spriteBatch.End();


           

            // TODO: Add your drawing code here



            base.Draw(gameTime);
        }

        /*
        private void controlPlayer(GameTime gametime)
        {
            player.update(gametime);


            shoot(gametime);

            // Get Thumbstick Controls
            player.position.X += currentGamePadState.ThumbSticks.Left.X * player.PlayerSpeed;
            player.position.Y -= currentGamePadState.ThumbSticks.Left.Y * player.PlayerSpeed;


            // Use the Keyboard or Dpad
            if (currentKeyboardState.IsKeyDown(Keys.Left) || currentGamePadState.DPad.Left == ButtonState.Pressed)
            {
                player.position.X -= player.PlayerSpeed; // think later of making an acessor method to mutate the position instead of doing this weird variable way. Might be impossible though, look at that .X part -- weird!
            }

            if (currentKeyboardState.IsKeyDown(Keys.Right) || currentGamePadState.DPad.Right == ButtonState.Pressed)
            {
                player.position.X += player.PlayerSpeed;
            }
<<<<<<< .mine
=======

            /*
            if (currentKeyboardState.IsKeyDown(Keys.Up) || currentGamePadState.DPad.Up == ButtonState.Pressed)
            {
                player.position.Y -= player.PlayerSpeed;
            }

            if (currentKeyboardState.IsKeyDown(Keys.Down) || currentGamePadState.DPad.Down == ButtonState.Pressed)
            {
                player.position.Y += player.PlayerSpeed;
            }
>>>>>>> .r7
            
        }
    */

        /*
        private void shoot(GameTime gameTime)
        {

            // Fire only every interval we set as the fireTime
            if (currentKeyboardState.IsKeyDown(Keys.Space) && gameTime.TotalGameTime - previousFireTime > fireTime)
            {
                // Reset our current time
                previousFireTime = gameTime.TotalGameTime;

                // Add the projectile, but add it to the front and center of the player
                //addProjectile(player.position + new Vector2(player.position.X + 259, player.position.Y + 42));
            }
        }
        */

        /*
        private void addProjectile(Vector2 position)
        {
            Projectile projectile = new Projectile();
            projectile.Initialize(GraphicsDevice.Viewport, position);
            projectiles.Add(projectile);
        }
        */

        /**
         * Updates projectiles depending on the projectile.Update() function. Also checks if a projectile is active and if it is not then delete.
         */ 
        /*
        private void updateProjectiles()
        {
            // Update the Projectiles
            for (int i = projectiles.Count - 1; i >= 0; i--)
            {
                projectiles[i].Update();

                if (projectiles[i].active == false)
                {
                    projectiles.RemoveAt(i);
                }
            }
        }
        */

        private void drawScore()
        {
            // Draw the score
               spriteBatch.DrawString(scoreFont, "Score: " + score, new Vector2(GraphicsDevice.Viewport.TitleSafeArea.X, GraphicsDevice.Viewport.TitleSafeArea.Y), Color.GreenYellow);
            // Draw the player health
               spriteBatch.DrawString(scoreFont, "Health: " + player.health, new Vector2(GraphicsDevice.Viewport.TitleSafeArea.X, GraphicsDevice.Viewport.TitleSafeArea.Y + 30), Color.Red);
        }
    }
}
